/*
 * virtKeyboard.java
 */
package organiser;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import javax.swing.JButton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;

/**
 * En klass som agerar som ett virituellt tangentbord på skärmen
 * @author Robin Gjurovski
 */
public class Keyboard extends JPanel implements Runnable, ActionListener {
    private ArrayList<JButton> ABCButton = new ArrayList<JButton>(); // en ArrayList som laggrar alla JButtons(tangenter)
    private ArrayList<JButton> _123Button = new ArrayList<JButton>();
    private ArrayList<JButton> abcButton = new ArrayList<JButton>();
    private JTextArea postText = new JTextArea();
    private JButton b123 = new JButton("123");
    private JButton bABC = new JButton("ABC");
    private JButton babc = new JButton("abc");
    private JPanel KeyboardPanel = new JPanel();
    private JTextArea inputArea = new JTextArea();
    private JPanel ABCKeyboard = new JPanel(); // panelen som kommer innehålla buttonsen som innehåller bokstäver
    private JPanel _123Keyboard = new JPanel(); //panelen som kommer innehålla buttonsen som har tecken
    private JPanel abcKeyboard = new JPanel();
    private JButton klock = new JButton(); // label som kommer innehålla klockan
    private JButton klock2 = new JButton();
    private JButton klock3 = new JButton();
    private String text = ""; // en sting som format texten i inputArea fielden
    private String[] abcKeys = {"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\u00E5", "",
        "a", "s", "d", "f", "g", "h", "j", "k", "l", "\u00F6", "\u00E4", "",
        "", "z", "x", "c", "v", "b", "n", "m", "Space"}; // Stringen som lagrar namnet på tangenterna
    private String[] ABCKeys = {"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\u00C5", "",
        "A", "S", "D", "F", "G", "H", "J", "K", "L", "\u00D6", "\u00C4", "",
        "", "Z", "X", "C", "V", "B", "N", "M", "Space"}; // Stringen som lagrar namnet på tangenterna
    private String[] _123Keys = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "+", "",
        "@", "[", "]", "/", "-", "=", "*", "%", "(", ")", "&", "",
        "", ".", ",", "?", "!", ";", ":", "\"", "Space"};
    private Font buttonFont = new Font("Sans-Serif", Font.PLAIN, 26);
    private ImageIcon backspaceIcon = new ImageIcon("C:/Java/Bilder/back.gif"); // ikon objekt till dem vissa knappar
    private ImageIcon homeIcon = new ImageIcon("C:/Java/Bilder/home.gif");
    private ImageIcon enterIcon = new ImageIcon("C:/Java/Bilder/return.gif");
    private JPanel cardsKeyboard = new JPanel(new CardLayout());
    private CardLayout clKeyboard = (CardLayout) (cardsKeyboard.getLayout());
    private JPanel cards;
    private CardLayout cl;
    private Home home;
    private Object defaults;

    public Keyboard(){
    }
    
    public Keyboard(Home home) {
        defaults = UIManager.getDefaults().get("Button.gradient");
        cards = home.getCards();
        cl = (CardLayout)cards.getLayout();
        
        text = postText.getText();
        inputArea.setText(text);
        KeyboardPanel.setSize(800, 480); // framens storlek
        inputArea.setSize(790, 232);
        inputArea.setLineWrap(true);
        inputArea.setPreferredSize(new Dimension(790, 232));
        inputArea.setFont(new Font("Sans-Serif", Font.PLAIN, 45));
        inputArea.setBorder(BorderFactory.createLineBorder( Color.BLACK, 2 ));
        inputArea.setBackground(new Color(245,245,245));
        inputArea.requestFocus(true); //sätter focus i inmatningsfönstret så man ser var markören befinner sig
        klock.setPreferredSize(new Dimension(99, 72));
        klock.setFont(buttonFont);
        klock.setHorizontalAlignment(JLabel.CENTER);
        klock.setBorder(BorderFactory.createLineBorder( Color.DARK_GRAY ));
        klock.setFocusable(false);
        klock.setForeground(Color.WHITE);
        klock2.setPreferredSize(new Dimension(99, 72));
        klock2.setFont(buttonFont);
        klock2.setHorizontalAlignment(JLabel.CENTER);
        klock2.setBorder(BorderFactory.createLineBorder( Color.DARK_GRAY ));
        klock2.setFocusable(false);
        klock2.setForeground(Color.WHITE);
        klock3.setPreferredSize(new Dimension(99, 72));
        klock3.setFont(buttonFont);
        klock3.setHorizontalAlignment(JLabel.CENTER);
        klock3.setBorder(BorderFactory.createLineBorder( Color.DARK_GRAY ));
        klock3.setFocusable(false);
        klock3.setForeground(Color.WHITE);
        ABCKeyboard.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); // panelen ges flowlayout där innehållet centreras
        ABCKeyboard.setPreferredSize(new Dimension(800, 304)); // anger storleken på panelen
        ABCKeyboard.setBorder(BorderFactory.createLineBorder( Color.BLACK ));
        _123Keyboard.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); // panelen ges flowlayout där innehållet centreras
        _123Keyboard.setPreferredSize(new Dimension(800, 304)); // anger storleken på panelen
        _123Keyboard.setBorder(BorderFactory.createLineBorder( Color.BLACK ));
        abcKeyboard.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); // panelen ges flowlayout där innehållet centreras
        abcKeyboard.setPreferredSize(new Dimension(800, 304)); // anger storleken på panelen
        abcKeyboard.setBorder(BorderFactory.createLineBorder( Color.BLACK ));
        b123.setPreferredSize(new Dimension(55, 72));
        b123.setForeground(Color.WHITE);
        b123.setBorder(BorderFactory.createLineBorder( Color.DARK_GRAY ));
        b123.addActionListener(this);
        babc.setPreferredSize(new Dimension(55, 72));
        babc.setForeground(Color.WHITE);
        babc.setBorder(BorderFactory.createLineBorder( Color.DARK_GRAY ));
        babc.addActionListener(this);
        bABC.setPreferredSize(new Dimension(55, 72));
        bABC.setForeground(Color.WHITE);
        bABC.setBorder(BorderFactory.createLineBorder( Color.DARK_GRAY ));
        bABC.addActionListener(this);
        cardsKeyboard.add(ABCKeyboard, "ABCKeyboard");
        cardsKeyboard.add(_123Keyboard, "123Keyboard");
        cardsKeyboard.add(abcKeyboard, "abcKeyboard");
        clKeyboard.show(cardsKeyboard, "ABCKeyboard");

        makeButtons(); // kommer fylla ArrayListen button med JButtons

        addListeners(); // lägger till ActionListeners på knapparna
        addButtons(); // lägger till buttonsen i JPanelen keyboard

        KeyboardPanel.add(inputArea, BorderLayout.NORTH); // lägger till inputAren i NORTH

        KeyboardPanel.add(cardsKeyboard, BorderLayout.CENTER); // lägger till keyboard i CENTER
        KeyboardPanel.setVisible(true);
    }

    public void makeButtons() { // skappar alla JButton utifrån String-arrayen 'keys'
        for (int i = 0; i < ABCKeys.length; i++) {
            ABCButton.add(new JButton(ABCKeys[i])); // skapar tangenterna med rätt namn från String-arrayen och lägger in dem i ArrayListen
            ABCButton.get(i).setFont(buttonFont); // byter teckensnitt på tangenterna
            ABCButton.get(i).setForeground(Color.white);
            ABCButton.get(i).setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
            ABCButton.get(i).setPreferredSize(new Dimension(66, 72)); // ändrar storleken på tangenterna
        }
        ABCButton.get(11).setIcon(backspaceIcon);
        ABCButton.get(24).setIcon(homeIcon);
        ABCButton.get(23).setIcon(enterIcon);
        ABCButton.get(32).setPreferredSize(new Dimension(110, 72)); // sätter space tangentens storlek större än dem anndra

        for (int i = 0; i < _123Keys.length; i++) {
            _123Button.add(new JButton(_123Keys[i])); // skapar tangenterna med rätt namn från String-arrayen och lägger in dem i ArrayListen
            _123Button.get(i).setFont(buttonFont); // byter teckensnitt på tangenterna
            _123Button.get(i).setForeground(Color.white);
            _123Button.get(i).setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
            _123Button.get(i).setPreferredSize(new Dimension(66, 72)); // ändrar storleken på tangenterna
        }
        _123Button.get(11).setIcon(backspaceIcon);
        _123Button.get(24).setIcon(homeIcon);
        _123Button.get(23).setIcon(enterIcon);
        _123Button.get(32).setPreferredSize(new Dimension(110, 72));

        for (int i = 0; i < abcKeys.length; i++) {
            abcButton.add(new JButton(abcKeys[i])); // skapar tangenterna med rätt namn från String-arrayen och lägger in dem i ArrayListen
            abcButton.get(i).setFont(buttonFont); // byter teckensnitt på tangenterna
            abcButton.get(i).setForeground(Color.white);
            abcButton.get(i).setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
            abcButton.get(i).setPreferredSize(new Dimension(66, 72)); // ändrar storleken på tangenterna
        }
        abcButton.get(11).setIcon(backspaceIcon);
        abcButton.get(24).setIcon(homeIcon);
        abcButton.get(23).setIcon(enterIcon);
        abcButton.get(32).setPreferredSize(new Dimension(110, 72));
    }

    public void addButtons() { // lägger till knapparna i panelerna
        for (int i = 0; i < ABCButton.size(); i++) {
            ABCKeyboard.add(ABCButton.get(i));
        }
        for (int i = 0; i < _123Button.size(); i++) {
            _123Keyboard.add(_123Button.get(i));
        }
        for (int i = 0; i < abcButton.size(); i++) {
            abcKeyboard.add(abcButton.get(i));
        }
        ABCKeyboard.add(babc);
        _123Keyboard.add(bABC);
        abcKeyboard.add(b123);
        ABCKeyboard.add(klock); // sist så läggs JLabeln med klocka till
        _123Keyboard.add(klock2);
        abcKeyboard.add(klock3);
    }

    public void setClock(String t) { // metoden returnerar den aktuella tiden på formen "hh:mm"
        klock.setText(t);
        klock2.setText(t);
        klock3.setText(t);
    }

    public void addListeners() { // metoden lägger till actionlistener på samtliga tangenter
        for (int i = 0; i < ABCButton.size(); i++) {
            ABCButton.get(i).addActionListener(this);
        }
        for (int i = 0; i < _123Button.size(); i++) {
            _123Button.get(i).addActionListener(this);
        }
        for (int i = 0; i < abcButton.size(); i++) {
            abcButton.get(i).addActionListener(this);
        }
    }

    public void addChar(String charIn, int pos) { // metoden lägger till en bokstav i Stringen på den plats där markören befinner sig
        if(inputArea.getText().length()<100){
            if (charIn.equalsIgnoreCase("Space")) {
                charIn = " ";
            }
            if (text.length() < 1) { // kontrollerar om Strängen är tillräkligt stor för att behöva delas
                text = charIn; // ändrar Strängen
            } else { // om strängen är längre så krävs det att den delas i delar och sedan modifieras och läggs ihop igen
                String[] p = new String[2]; // skappar en string array som sparar dem olika delarna av strängen
                p[0] = text.substring(0, pos); // första delen av strängen
                p[1] = text.substring(pos, text.length()); // anndra delen
                text = p[0] += charIn + p[1]; // lägger samman delarna igen med det tillagda tecknet mellan
            }
            inputArea.setText(text);
            inputArea.setCaretPosition(pos + 1); // sätter tillbaka markören till samma position som den var i före ändring
        }
    }

    public void subtractChar(int pos) {
        if (text.length() < 2) { //om strängen <2 så tas allt bort
            text = "";
        } else {
            String[] p = new String[2]; //lagrar dem två delarna av strängen
            p[0] = text.substring(0, pos - 1); //tar ut första delen minus den position som skulle bort
            p[1] = text.substring(pos, text.length()); // resten av strängen
            text = p[0] + p[1]; //sammanfogar strängen igen
        }
        inputArea.setText(text); //anger den nya texten
        inputArea.setCaretPosition(pos - 1); // anger den nya positionen
    }

    public void actionPerformed(ActionEvent e) { // eventhanterare
        Object source = e.getSource();
        int pos = inputArea.getCaretPosition(); //hämtar markörens position och lagrar den i pos
        System.out.println(pos); //**********************************************************************************

        //Loop för bokstäver
        for (int i = 0; i < ABCButton.size(); i++) { // loopar igenom alla buttons för att hitta vilken som stämmer överens med source
            if (source == ABCButton.get(i) && source != ABCButton.get(11) && source != ABCButton.get(23) && source != ABCButton.get(24)) { //om det är någon av alla knapparna förutom bkspc enter och home
                addChar(ABCButton.get(i).getText(), pos); //anropas metoden addChar och tecknet som skall läggas till och positionen skickas med
                break;
            }
        }
        for (int i = 0; i < abcButton.size(); i++) { // loopar igenom alla buttons för att hitta vilken som stämmer överens med source
            if (source == abcButton.get(i) && source != abcButton.get(11) && source != abcButton.get(23) && source != abcButton.get(24)) { //om det är någon av alla knapparna förutom bkspc enter och home
                addChar(abcButton.get(i).getText(), pos); //anropas metoden addChar och tecknet som skall läggas till och positionen skickas med
                break;
            }
        }
        //Loop för siffror och tecken och gemensamma tecken
        for (int i = 0; i < _123Button.size(); i++) {
            if (source == _123Button.get(i) && source != _123Button.get(11) && source != _123Button.get(23) && source != _123Button.get(24)) { //om det är någon av alla knapparna förutom bkspc enter och home
                addChar(_123Button.get(i).getText(), pos); //anropas metoden addChar och tecknet som skall läggas till och positionen skickas med
                break;
            } else if (source == ABCButton.get(11) || source == _123Button.get(11) || source == abcButton.get(11)) { // om backspace
                if (inputArea.getText().length() > 0 && pos > 0) { //utförs endast om det finns något att ta bort i Textarean och om positionen är >0
                    subtractChar(pos);
                    break;
                    //BACKSPACE!
                }
            } else if (source == ABCButton.get(23) || source == _123Button.get(23) || source == abcButton.get(23)) {
                UIManager.put("Button.gradient", defaults);
                postText.setText(inputArea.getText());
                cl.show(cards, "PostIt");
                //ENTER!
            } else if (source == ABCButton.get(24)) {
                //HOME!
            } else if (source == b123) {
                clKeyboard.show(cardsKeyboard, "123Keyboard");
            } else if (source == bABC) {
                clKeyboard.show(cardsKeyboard, "ABCKeyboard");
            } else if (source == babc){
                clKeyboard.show(cardsKeyboard, "abcKeyboard");
            }
        }
        inputArea.requestFocus(true); //sätter focus i inmatningsfönstret så man ser var markören befinner sig
    }

    public Object getDefaults() {
        return defaults;
    }

    public void setDefaults(Object defaults) {
        this.defaults = defaults;
    }

    public JPanel getJPanel(){
        return KeyboardPanel;
    }

    public void setText(String inText){
        postText.setText(inText);
    }

    public void run() { // metoden för att hålla reda på klockan
        while (true) {
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
            setClock(sdf.format(cal.getTime()));
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ex) {
            }
        }
    }
}
